package com.lzyyj.common;

import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;

import javax.imageio.ImageIO;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class ImageUtil {

	private static final Log log = LogFactory.getLog(ImageUtil.class);
	
	/**
	 * 获取网络图片内容
	 * @param imgUrl 图片地址
	 * @param baseUrl 基本路径，用于补全图片地址
	 * @param refererUrl 引用路径，防盗链时用到
	 * @return
	 */
	public static BufferedImage getImageFromUrl(String imgUrl, String baseUrl, String refererUrl) {
		return getImageFromUrl(imgUrl, baseUrl, refererUrl, null);
	}

	/**
	 * 获取网络图片内容
	 * @param imgUrl 图片地址
	 * @param baseUrl 基本路径，用于补全图片地址
	 * @param refererUrl 引用路径，防盗链时用到
	 * @return
	 */
	public static BufferedImage getImageFromUrl(String imgUrl, String baseUrl, String refererUrl, List<String> cookies) {
		BufferedImage image = null;
		
		if(imgUrl!=null){

			if (!imgUrl.startsWith("http:")){
				if (baseUrl!=null){
					if (baseUrl.endsWith("/")){
						if (imgUrl.startsWith("/")){
							imgUrl = baseUrl+imgUrl.substring(1);
						}else{
							imgUrl = baseUrl+imgUrl;
						}
					}else{
						if (imgUrl.startsWith("/")){
							imgUrl = baseUrl+imgUrl;
						}else{
							imgUrl = baseUrl+"/"+imgUrl;
						}
					}
				}
			}
			if (refererUrl==null){
		        refererUrl = baseUrl.substring(0,imgUrl.indexOf('/',8));
			}

			try {
				URL url = new URL(imgUrl);
				URLConnection connection = url.openConnection();
				connection.setDoOutput(true);
				connection.setRequestProperty("referer", refererUrl);       //通过这个http头的伪装来反盗链
				if (cookies!=null){
					for(String cookie: cookies){
						String c = cookie.split(";", 2)[0];
						connection.addRequestProperty("Cookie", c);
					}
				}
				image = ImageIO.read(connection.getInputStream());
				List<String> newCookies = connection.getHeaderFields().get("Set-Cookie");
				if (newCookies!=null){
					cookies.clear();
					for(String cookie:newCookies){
						cookies.add(cookie);
					}
				}
				
			} catch (IOException e) {
				log.info("获取网络图片失败："+e);
			}
		}
		
		return image;
	}

	/**
	 * 保存图片
	 * @param image
	 * @param imagePath
	 * @param ext
	 */
	public static void saveImage(BufferedImage image, String imagePath, String ext) {
		String filePath = FileUtil.getFullPath(imagePath);
		
	    try {
			FileOutputStream fout;
			fout=new FileOutputStream(filePath);
			if("gif".equals(ext)||"png".equals("png"))
			{
			     ImageIO.write(image, ext, fout);
			}else{
			    ImageIO.write(image, "jpg", fout);
			}
			fout.flush();
			fout.close();
		} catch (IOException e) {
			e.printStackTrace();
			log.warn("图片保存失败："+e);
		}
	}

	/**
	 * 创建缩略图，宽度大于1080px的图片缩小到不小于540px，
	 * @param image		源图
	 * @param savePath		保存路径
	 * @param targetWidth	目标图宽度
	 * @param targetHeight	目标图高度
	 * @param targetRatio	目标图宽高比
	 * @param tolerance		宽高比变形容限
	 * @return
	 */
	public static BufferedImage createThumbnailImage(BufferedImage image, String savePath, int targetWidth, int targetHeight, float targetRatio, float tolerance) {
		BufferedImage resultImage = null;
	
		// 目标宽高比
		if (targetWidth>0&&targetHeight>0){
			targetRatio = (0f+targetWidth)/targetHeight;
		}else if (targetHeight<=0){
			targetHeight = (int)(targetWidth/targetRatio);
		}else{
			targetWidth = (int)(targetHeight*targetRatio);
		}
		
		int width = image.getWidth();
		int height = image.getHeight();
		
		// 实际宽高比
		float ratio = (0f+image.getWidth()) / image.getHeight();
		
		// 宽高比差
		if  ( Math.abs(ratio - targetRatio)/targetRatio < tolerance){
			// 宽高比偏差不大，不用裁切, 可直接缩小到指定尺寸
			// 图片尺寸超标，需要缩放处理
			if (width>targetWidth||height>targetHeight){
				resultImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
				resultImage.getGraphics().drawImage(image.getScaledInstance(targetWidth, targetHeight,java.awt.Image.SCALE_SMOOTH), 0, 0, null);  
			}
		}else{
			// 宽高比偏差太大，如果要进行缩放处理的话，还需要进行适当裁切
			if (width>targetWidth||height>targetHeight){
				// 图片也较大，还需要进行缩略处理
				if (ratio > targetRatio){
					// 宽度过大，需要进行一定的裁切处理，为减少被裁切的部分，在容限内加大横向缩放比例,即多收缩一些，使更多图像内容收缩进裁切范围内
					// 以高度为基准计算缩放比例，
					resultImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
					int w = (int)(width/((0f+height)/targetHeight-tolerance));
					resultImage.getGraphics().drawImage(image.getScaledInstance(w, targetHeight,java.awt.Image.SCALE_SMOOTH), (targetWidth-w)/2, 0, null);  
				}else{
					// 高度过大，需要进行一定的切边处理，并进行横向拉伸，以达到要求的比例
					resultImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
					// 以宽度为基准，按宽高比容限
					int h = (int)(height/((0f+width)/targetWidth-tolerance));
					resultImage.getGraphics().drawImage(image.getScaledInstance(targetWidth, h,java.awt.Image.SCALE_SMOOTH), 0, (targetHeight-h)/2, null);  
				}
			}else{
				// 图片不大，只需进行裁切处理
				if (ratio > targetRatio){
					// 宽度过大，需要进行一定的裁切处理，为减少被裁切的部分，在容限内加大横向缩放比例,即多收缩一些，使更多图像内容收缩进裁切范围内
					// 高度不变，
					targetHeight = height;
					// 重新计算宽度
					targetWidth = (int)(targetHeight*targetRatio);
					resultImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
					// 宽度适当收缩，避免裁切过多
					int w = (int)(width/((0f+height)/targetHeight-tolerance));
					resultImage.getGraphics().drawImage(image.getScaledInstance(w, targetHeight,java.awt.Image.SCALE_SMOOTH), (targetWidth-w)/2, 0, null);
				}else{
					// 高度过大，需要进行一定的切边处理，并进行横向拉伸，以达到要求的比例
					// 宽度不变
					targetWidth = width;
					// 重新计算高度
					targetHeight = (int)(targetWidth*targetRatio);
					resultImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
					// 以宽度为基准，按宽高比容限
					int h = (int)((0f+width)/targetWidth-tolerance)*targetHeight;
					resultImage.getGraphics().drawImage(image.getScaledInstance(targetWidth, h,java.awt.Image.SCALE_SMOOTH), 0, (targetHeight-h)/2, null);  
				}
			}
		}
		
		return resultImage;
	}

	/**
	 * 创建适当大小的图片，宽度及高度不大于指定尺寸，超过的则按整倍数缩小到符合要求的大小
	 * @param image
	 * @param tITLE_IMAGE_PATH2
	 * @return
	 */
	public static BufferedImage createProperImage(BufferedImage image, int maxWidth, int maxHeight) {
		BufferedImage resultImage = null;
		
		int width = image.getWidth();
		int height = image.getHeight();
		float scale = 1.0f;
		// 如果尺寸超标就成倍缩小到不超标
		while(width>maxWidth||height>maxHeight){
			scale /= 2; 
			width = (int)(image.getWidth() * scale);
			height = (int)(image.getHeight() * scale);
		}
		// 直到缩小至最大限制尺寸以下
		
		resultImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);  
		resultImage.getGraphics().drawImage(image.getScaledInstance(width, height,java.awt.Image.SCALE_SMOOTH), 0, 0, null);  
		
		return resultImage;
	}

}
